﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSE.Framework.Communication.Configuration.Adapters.File;
using PSE.Framework.Communication.Adapters.File;
using PSE.Framework.Communication.Adapters;

namespace PSE.Framework.Communication.Client.File
{
    /// <summary>
    /// Classe base dos clients de exportação de arquivos
    /// </summary>
    /// <typeparam name="TOpenParameter">Tipo do parâmetro de abertura do processo</typeparam>
    public abstract class FileOutputClient<TOpenParameter> : BaseOutputClient<TOpenParameter>
        where TOpenParameter : class
    {
        #region Construtores
        /// <summary>
        /// Construtor padrão
        /// </summary>
        public FileOutputClient()
        {
        }
        #endregion

        #region Adapter
        /// <summary>
        /// Adapter encapsulado pelo client
        /// </summary>
        protected new IStreamOutputAdapter Adapter
        {
            get { return (IStreamOutputAdapter)base.Adapter; }
        }
        #endregion

        #region FileStatus
        /// <summary>
        /// Status da importação do arquivo
        /// </summary>
        public FileStatus FileStatus
        {
            get
            {
                if (this.Adapter != null)
                {
                    switch (this.Adapter.StreamStatus)
                    {
                        case StreamStatus.Created:
                            return FileStatus.Created;
                        case StreamStatus.Opened:
                            return FileStatus.Opened;
                        case StreamStatus.Closed:
                            return FileStatus.Closed;
                        default:
                            return FileStatus.Created;
                    }
                }
                else
                {
                    return FileStatus.Created;
                }
            }
        }
        #endregion

        #region OpenFile
        /// <summary>
        /// Abre o arquivo para gravação de registros
        /// </summary>
        public virtual void OpenFile()
        {
            this.VerifyIsOpened();

            this.Adapter.OpenStream();
        }

        /// <summary>
        /// Abre o arquivo para gravação de registros
        /// </summary>
        /// <param name="parameter">Parâmetro de abertura do arquivo</param>
        public virtual void OpenFile(FileOpenParameter parameter)
        {
            this.VerifyIsOpened();

            this.Adapter.OpenStream(parameter);
        }
        #endregion

        #region CloseFile
        /// <summary>
        /// Fecha o arquivo e encerra a gravação de registros
        /// </summary>
        /// <param name="message">Mensagem de fechamento do stream</param>
        public virtual void CloseFile()
        {
            this.VerifyIsOpened();

            this.Adapter.CloseStream();
        }

        #endregion

        #region CancelFile
        /// <summary>
        /// Cancela a exportação do arquivo
        /// </summary>
        public virtual void CancelFile()
        {
            this.VerifyIsOpened();

            this.Adapter.CancelStream();
        }
        #endregion

        #region WriteRecord
        /// <summary>
        /// Grava um registro no arquivo
        /// </summary>
        /// <param name="record">Registro a ser gravado</param>
        /// <param name="action">Action do registro</param>
        public void WriteRecord(object record, string action)
        {
            if (record == null)
                throw new ArgumentNullException("record");
            if (string.IsNullOrEmpty(action))
                throw new ArgumentNullException("action");

            this.VerifyIsOpened();

            this.Adapter.Send(record, action);
        }
        #endregion
    }
}
